package com.fangs.kotlin_banner.utils

import android.util.DisplayMetrics
import android.view.WindowManager
import android.app.Activity
import android.content.Context
import android.graphics.Rect
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.Window
import java.lang.Exception

object DisplayUtils {
    private var screenWidth = 0
    private var screenHeight = 0
    private var contentHeight = 0
    private var titleBarHeight = 0
    private var statusBarHeight = 0
    private var dm: DisplayMetrics? = null
    fun getDisplayMetrics(context: Context): DisplayMetrics? {
        if (dm == null) {
            dm = DisplayMetrics()
            val manager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
            manager.defaultDisplay.getMetrics(dm)
        }
        return dm
    }

    fun getScreenWidth(context: Context): Int {
        if (screenWidth == 0) {
            screenWidth = getDisplayMetrics(context)!!.widthPixels
        }
        return screenWidth
    }

    fun getScreenHeight(context: Context): Int {
        if (screenHeight == 0) {
            screenHeight = getDisplayMetrics(context)!!.heightPixels
        }
        return screenHeight
    }

    fun getContentViewHeight(activity: Activity): Int {
        if (contentHeight == 0) {
            contentHeight = activity.window.findViewById<View>(Window.ID_ANDROID_CONTENT).height
        }
        return contentHeight
    }

    fun getTitleBarHeight(activity: Activity): Int {
        if (titleBarHeight == 0) {
            val contentTop = activity.window.findViewById<View>(Window.ID_ANDROID_CONTENT).top
            titleBarHeight = contentTop - getStatusBarHeight(activity as Context)
        }
        return titleBarHeight
    }

    fun getStatusBarHeight(context: Context): Int {
        if (statusBarHeight == 0) {
            try {
                val c = Class.forName("com.android.internal.R\$dimen")
                val obj = c.newInstance()
                val field = c.getField("status_bar_height")
                val x = field[obj].toString().toInt()
                statusBarHeight = context.resources.getDimensionPixelSize(x)
            } catch (e: Exception) {
                if (context is Activity) {
                    statusBarHeight = getStatusBarHeight(
                        context
                    )
                }
            }
        }
        return statusBarHeight
    }

    private fun getStatusBarHeight(activity: Activity): Int {
        val rect = Rect()
        activity.window.decorView.getWindowVisibleDisplayFrame(rect)
        return rect.top
    }

    /**
     * Determines if given points are inside view
     *
     * @param x    - x coordinate of point
     * @param y    - y coordinate of point
     * @param view - view object to compare
     * @return true if the points are within view bounds, false otherwise
     */
    fun isPointInsideView(x: Float, y: Float, view: View): Boolean {
        val location = IntArray(2)
        view.getLocationOnScreen(location)
        val viewX = location[0]
        val viewY = location[1]

        // point is inside view bounds
        return x > viewX && x < viewX + view.width && y > viewY && y < viewY + view.height
    }

    /**
     * @param context
     * @param dipValue
     * @return
     */
    fun dip2px(context: Context?, dipValue: Float): Int {
        if (context == null) {
            return dipValue.toInt()
        }
        val scale = context.resources.displayMetrics.density
        return (dipValue * scale + 0.5f).toInt()
    }

    /**
     * @param context
     * @param pxValue
     * @return
     */
    fun px2dip(context: Context?, pxValue: Float): Int {
        if (context == null) {
            return pxValue.toInt()
        }
        val scale = context.resources.displayMetrics.density
        return (pxValue / scale + 0.5f).toInt()
    }

    /**
     * @param context
     * @param px
     * @return
     */
    fun px2sp(context: Context?, px: Float): Float {
        if (context == null) {
            return px.toInt().toFloat()
        }
        val scaledDensity = context.resources.displayMetrics.scaledDensity
        return px / scaledDensity
    }

    /**
     * @param context
     * @param sp
     * @return
     */
    fun sp2px(context: Context?, sp: Float): Float {
        if (context == null) {
            return sp
        }
        val r = context.resources
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, r.displayMetrics)
    }

    /**
     * 测量视图尺寸
     *
     * @param view 视图
     * @return arr[0]: 视图宽度, arr[1]: 视图高度
     */
    fun measureView(view: View): IntArray {
        var lp = view.layoutParams
        if (lp == null) {
            lp = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
            )
        }
        val widthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width)
        val lpHeight = lp.height
        val heightSpec: Int
        heightSpec = if (lpHeight > 0) {
            View.MeasureSpec.makeMeasureSpec(
                lpHeight,
                View.MeasureSpec.EXACTLY
            )
        } else {
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        }
        view.measure(widthSpec, heightSpec)
        return intArrayOf(view.measuredWidth, view.measuredHeight)
    }

    /**
     * 获取测量视图宽度
     *
     * @param view 视图
     * @return 视图宽度
     */
    fun getMeasuredWidth(view: View): Int {
        return measureView(view)[0]
    }

    /**
     * 获取测量视图高度
     *
     * @param view 视图
     * @return 视图高度
     */
    fun getMeasuredHeight(view: View): Int {
        return measureView(view)[1]
    }
}